package org.example.aienglishapp_login.config.login;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.annotation.web.configurers.HeadersConfigurer;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import static org.springframework.security.config.Customizer.withDefaults;

@Configuration
@EnableWebSecurity
@EnableMethodSecurity(prePostEnabled = true)
public class SecurityConfig {

    private final CustomUserDetailsService userDetailsService;

    private final CustomAccessDeniedHandler accessDeniedHandler;

    private final CustomAuthenticationEntryPoint authenticationEntryPoint;

    private final JwtTokenFilter jwtTokenFilter;

    @Autowired
    public SecurityConfig(CustomUserDetailsService userDetailsService,
                          CustomAccessDeniedHandler accessDeniedHandler,
                          CustomAuthenticationEntryPoint authenticationEntryPoint,
                          JwtTokenFilter jwtTokenFilter) {
        this.userDetailsService = userDetailsService;
        this.accessDeniedHandler = accessDeniedHandler;
        this.authenticationEntryPoint = authenticationEntryPoint;
        this.jwtTokenFilter = jwtTokenFilter;
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
                .csrf(AbstractHttpConfigurer::disable)
                .authorizeHttpRequests(authorize -> authorize
                        .requestMatchers("/api/users/**").permitAll()
                        .requestMatchers("/api/roles/**").hasAuthority("ROLE_admin")
                        .requestMatchers("/api/users/{userId}/username").hasAuthority("修改用户名")
                        .requestMatchers("/avatar/**").permitAll()
                        .requestMatchers("/icon/**").permitAll()
                        .requestMatchers("/api/operationlogs/**").permitAll()
                        .requestMatchers("/api/loginlog/**").permitAll()
                        .requestMatchers("/api/speech/**").permitAll()
                        .requestMatchers("/api/books/**").permitAll()
                        .requestMatchers("/api/chapters/**").permitAll()
                        .requestMatchers("/api/sentences/**").permitAll()
                        .requestMatchers("/api/words/**").permitAll()
                        .requestMatchers("/api/words/wordbooks").permitAll()
                        .requestMatchers("/api/word/user/**").permitAll()
                        .requestMatchers("/api/word/user/progress").permitAll()
                        .requestMatchers("/api/word/user/errorWords").permitAll()
                        .requestMatchers("/api/word/user/progress/").permitAll()
                        .requestMatchers("/api/articles/**").permitAll()
                        .requestMatchers("/api/article/**").permitAll()
                        .requestMatchers("/api/translations/**").permitAll()
                        .requestMatchers("/api/translations/translateAndSave").permitAll()
                        .requestMatchers("/api/favorites/**").permitAll()
                        .requestMatchers("/api/daily-goals/**").permitAll()
                        .requestMatchers("/api/learning-stats/**").permitAll()
                        .requestMatchers("/api/user-progress/**").permitAll()
                        .requestMatchers("/api/available-courses/**").permitAll()
                        .requestMatchers("/api/enrolled-courses/**").permitAll()
                        .requestMatchers("/api/enroll-course/**").permitAll()
                        .requestMatchers("/api/notifications/**").permitAll()
                        .requestMatchers("/ws/**").permitAll()
                        .requestMatchers(HttpMethod.OPTIONS, "/**").permitAll() // 允许所有OPTIONS请求
                        .anyRequest().authenticated()
                )
                .logout(logout -> logout
                        .logoutUrl("/logout")
                        .logoutSuccessUrl("/login?logout")
                        .invalidateHttpSession(true)
                        .deleteCookies("JSESSIONID")
                        .permitAll()
                )
                .rememberMe(rememberMe -> rememberMe
                        .key("uniqueAndSecret")
                        .tokenValiditySeconds(86400 * 30)
                        .userDetailsService(userDetailsService)
                )
                .httpBasic(withDefaults())
                .exceptionHandling(exceptionHandling -> exceptionHandling
                        .accessDeniedHandler(accessDeniedHandler)
                        .authenticationEntryPoint(authenticationEntryPoint)
                )
                .headers(headers -> headers
                        .frameOptions(HeadersConfigurer.FrameOptionsConfig::sameOrigin)
                        .contentSecurityPolicy(contentSecurityPolicy -> contentSecurityPolicy.policyDirectives("script-src 'self'"))
                )
                .addFilterBefore(jwtTokenFilter, UsernamePasswordAuthenticationFilter.class);


        http.userDetailsService(userDetailsService);

        return http.build();
    }
}